import { BattleFactory } from './BattleFactory';
import { BattleMap } from './BattleMap';
import { CommandValidator } from './CommandValidator';
import { BuildingConfig, CommandFailLimit, MapSettings, ResourceConfig, RoundLimit, UnitConfig, TERRAIN_NAMES, MapConfigs, BasePositionConfigs, getUnitConfig, getBuildingConfig, SplashDamageRatio, CodeExecutionFailLimit } from './Const';
import { BattleStatus, BuildingType, CommandType, EntityType, TildeType, UnitType } from './Enums';
import { BattleResultData, PlayerStatsModel, BattleMemModel, BuildingModel, CommandParam, CommandParamMap, FailCommandModel, CommandExecutionDetailModel, EntityExecutionState, GameStateModel, PlayerInfoModel, RoundProcessResult, UnitModel } from './Model';

import { GameConfig } from '../config';
import { battleScene } from '../view/scene/BattleSceneManager';

export class BattleSystem {
    public map: BattleMap = null;
    public factory: BattleFactory = null;
    public validator: CommandValidator = null;
    public status: BattleStatus = BattleStatus.init;
    private players: string[] = [];
    private battleResult: BattleResultData = null;
    private currentRound: number = 0;
    private currentRoundCommands: {[key: string]: CommandParam<keyof CommandParamMap>[]} = {};
    private currentRoundEntities: Set<string> = new Set(); // 当前回合已执行的实体集合
    private currentRoundNewEntities: Set<string> = new Set(); // 当前回合新生产的实体集合
    private logger: any = null; // 日志记录器
    private roundLimit: number = RoundLimit; // 最大回合数，默认使用常量值

    /**
     * 批量处理回合命令入口
     * 接收单个玩家当前回合的命令集，立即执行该玩家的命令
     * 当所有玩家都提交命令后才进行结果校验和清理缓存
     * @param playerCommands 玩家的回合命令数组
     * @returns 提交结果
     */
    public submitRoundCommands(player: string, playerCommands: CommandParam<keyof CommandParamMap>[], codeExecutionFailed: boolean = false): { success: boolean; result: RoundProcessResult; error?: string } {
        if (!this.validator) {
            this.status = BattleStatus.end;
            return { success: false, result: null, error: '战斗系统未初始化, 请先执行init命令' };
        }

        // 处理玩家代码执行异常
        if (codeExecutionFailed) {
            const playerObj = this.map.getPlayer(player);
            if (!playerObj) {
                this._log('error', 'battle', `玩家${player}不存在`, { player: player });
                return { success: false, result: null, error: `玩家${player}不存在` };
            }

            playerObj.addCodeExecutionFail();
            const failCount = playerObj.getCodeExecutionFailCount();

            this._log('info', 'battle', `玩家${player}代码执行异常`, {
                player: player,
                failCount: failCount,
                limit: CodeExecutionFailLimit
            });

        }

        const battleMem = this.getBattleMemModel();

        // 状态前置校验 (这里不通过是服务器逻辑有问题)
        const validationResult = this.validator.validateRoundCommands(battleMem, player);
        if (!validationResult.valid) {
            this._log('error', 'round', validationResult.error, { "player": player, "currentRound": this.currentRound });
            this.status = BattleStatus.end;
            return { success: false, result: null, error: validationResult.error };
        }

        // 玩家命令集的合法性校验
        const validationPlayerResult = this.validator.validatePlayerCommandsOwner(battleMem, player, playerCommands);
        if (!validationPlayerResult.valid) {
            this._log('error', 'round', validationPlayerResult.error, { "player": player, "currentRound": this.currentRound });
            // 玩家异常提交，直接判负结束
            this.handlePlayerInvalidSubmission(player, validationPlayerResult.error);
            return { success: false, result: null, error: validationPlayerResult.error };
        }

        // 存储玩家的当前回合命令
        this.currentRoundCommands[player] = playerCommands;

        this._log('info', 'round', `收到玩家命令`, { "player": player, "currentRound": this.currentRound, "commandCount": playerCommands.length });

        // 立即执行该玩家的命令并返回执行结果
        const playerExecutionResult = this.executePlayerCommands(player, playerCommands);
        let hasError = playerExecutionResult.error;
        const playerResult: RoundProcessResult = {
            round: this.currentRound,
            success: playerExecutionResult.success,
            battleEnded: false,
            playerCommandExecutionDetails: playerExecutionResult.commandDetails || [],
        };

        // 检查是否所有玩家都提交了命令
        const submittedPlayers = Object.keys(this.currentRoundCommands);
        const allPlayersSubmitted = this.players.every((player) => submittedPlayers.indexOf(player) !== -1);
        if (allPlayersSubmitted) {
            // 所有玩家都提交后，进行最终的战斗结束检查
            const finalRoundResult = this.finalizeCurrentRound();
            playerResult.battleEnded = finalRoundResult.battleEnd;
            playerResult.endCommand = finalRoundResult.endCommand;
            if (hasError == "" && finalRoundResult.error != "") {
                hasError = finalRoundResult.error;
            }
        }

        return {success: true, result: playerResult, error: hasError};
    }

    /**
     * 执行单个玩家的命令
     * @param player 玩家ID
     * @param playerCommands 玩家命令列表
     * @returns 执行结果
     */
    private executePlayerCommands(player: string, playerCommands: CommandParam<keyof CommandParamMap>[]): { success: boolean; error?: string; commandDetails: CommandExecutionDetailModel[] } {
        try {

            let playerCommandDetails: CommandExecutionDetailModel[] = [];

            // 顺序执行该玩家的所有命令
            for (const cmd of playerCommands) {
                const result = this.cmd(cmd);

                // 记录命令执行详情
                const commandDetail = this.recordCommandExecutionDetail(cmd, result.valid, result.notValidMsg || '');
                playerCommandDetails.push(commandDetail);
            }

            this._log('info', 'round', `玩家命令执行完成`, { "player": player, "currentRound": this.currentRound });

            return { success: true, error: null, commandDetails: playerCommandDetails };
        } catch (e) {
            const errorMsg = `玩家 ${player} 第 ${this.currentRound} 回合命令执行时发生异常:`;
            this._log('error', 'round', errorMsg, { "player": player, "round": this.currentRound, "error": e.message, "stack": e.stack });
            return { success: false, error: errorMsg, commandDetails: [] };
        }
    }

    /**
     * 完成当前回合处理（所有玩家都提交命令后调用）
     * @returns 回合处理结果
     */
    private finalizeCurrentRound(): { battleEnd: boolean; endCommand?: CommandParam<CommandType.end>; error?: string } {

        try {
            // 检查战斗是否结束
            let battleEnd = this.checkBattleResult();
            if (battleEnd) {
                this.status = BattleStatus.end;
            }

            // 自增回合数
            this.currentRound++;
            // 清理已处理的回合命令
            this.currentRoundCommands = {};
            // 清理已执行的实体集合
            this.currentRoundEntities.clear();
            // 清理新生产的实体集合
            this.currentRoundNewEntities.clear();

            // 如果战斗结束，创建并执行end命令
            let endCommand: CommandParam<CommandType.end> = null;
            if (battleEnd) {
                if (this.battleResult) {
                    endCommand = {
                        type: CommandType.end,
                        player: 'system',
                        round: this.currentRound,
                        param: {
                            result: this.battleResult
                        }
                    };
                    const endResult = this._commandExecution(endCommand);
                    this._log('info', 'cmd', 'end命令执行完成', { "success": endResult.checkResult.valid });
                }
                this._log('info', 'round', '战斗已结束');
            }

            return { battleEnd: battleEnd, endCommand: endCommand, error: null };
        } catch (e) {
            const errorMsg = `第 ${this.currentRound} 回合最终处理时发生异常:`;
            this._log('error', 'round', errorMsg, { "round": this.currentRound, "error": e.message, "stack": e.stack });

            // 即使发生异常，如果战斗已经结束（比如由于代码执行失败），也要返回endCommand
            let endCommand: CommandParam<CommandType.end> = null;
            let battleEnd = this.status === BattleStatus.end;

            if (battleEnd && this.battleResult) {
                endCommand = {
                    type: CommandType.end,
                    player: 'system',
                    round: this.currentRound,
                    param: {
                        result: this.battleResult
                    }
                };
                try {
                    const endResult = this._commandExecution(endCommand);
                    this._log('info', 'cmd', 'end命令执行完成（异常处理中）', { "success": endResult.checkResult.valid });
                } catch (endError) {
                    this._log('error', 'cmd', 'end命令执行失败', { "error": endError.message });
                }
            }

            return { battleEnd: battleEnd, endCommand: endCommand, error: errorMsg };
        }
    }



    /**
     * 处理玩家异常提交，直接判负结束战斗
     * @param player 异常提交的玩家ID
     * @param error 异常错误信息
     */
    private handlePlayerInvalidSubmission(player: string, error: string): void {
        this.status = BattleStatus.end;

        const playerStatsMap: {[key: string]: PlayerStatsModel} = {};
        const failedCommandsMap: {[key: string]: FailCommandModel[]} = {};
        let winner = player;
        this.players.forEach((playerId) => {
            if (playerId !== player) {
                winner = playerId;
            }
            failedCommandsMap[playerId] = this.map.getPlayer(playerId).getFailedCommands();
            playerStatsMap[playerId] = this.getPlayerStats(playerId) as PlayerStatsModel;
        });
        const battleResult: BattleResultData = {
            winner: winner,
            loser: player,
            msg: `玩家${player}的异常提交: ${error}，自动判负，战斗结束！`,
            playerStats: playerStatsMap,
            failedCommands: failedCommandsMap,
        };
        this.battleResult = battleResult;
        const endCommand = {
            type: CommandType.end,
            player: 'system',
            round: this.currentRound,
            param: {
                result: this.battleResult
            }
        };
        this._commandExecution(endCommand);
    }

    /**
     * 单个命令执行入口
     * @param cmd 命令
     * @returns 是否执行成功
     */
    public cmd(cmd: CommandParam<keyof CommandParamMap>): { valid: boolean; notValidMsg?: string, error?: string } {
        this._log('info', 'cmd', '开始执行命令', { "type": cmd.type, "player": cmd.player, "round": cmd.round });

        if (cmd.type !== CommandType.init) {
            // 进行基础命令验证
            const validationResult = this.validator.validateBasicCommand(cmd, this.getBattleMemModel());
            if (!validationResult.valid) {
                this._log('error', 'cmd', validationResult.notValidMsg, { "type": cmd.type, "player": cmd.player, "currentRound": this.currentRound });
                this.recordFailedCommand(cmd, validationResult.notValidMsg);
                return { valid: false, notValidMsg: validationResult.notValidMsg };
            }
            if (validationResult.entityKey) {
                this.currentRoundEntities.add(validationResult.entityKey);
            }
        }

        //命令执行
        try {
            const executionResult = this._commandExecution(cmd);
            this._log('info', 'cmd', `${cmd.type}命令执行完成`, { "type": cmd.type, "valid": executionResult.checkResult.valid });
            return { valid: executionResult.checkResult.valid, notValidMsg: executionResult.checkResult.error };
        } catch (e) {
            const errorMsg = `${cmd.type}命令执行异常`;
            this._log('error', 'cmd', errorMsg, { "cmd": cmd, "error": e.message || e, "stack": e.stack });
            return { valid: false, error: errorMsg };
        }
    }

    /**
     * 命令执行内部执行
     */
    private _commandExecution(cmd: CommandParam<keyof CommandParamMap>): { resultCmd: CommandParam<keyof CommandParamMap> | false; checkResult: { valid: boolean; error?: string } } {

        let resultCmd: CommandParam<keyof CommandParamMap>;
        let checkResult: { valid: boolean; error?: string } = { valid: true };

        // 执行命令逻辑
        switch (cmd.type) {
            case CommandType.init: {
                const result = this._cmdInit(cmd as CommandParam<CommandType.init>);
                resultCmd = result.resultCmd;
                checkResult = result.checkResult;
                break;
            }
            case CommandType.move: {
                const result = this._cmdMoveTo(cmd as CommandParam<CommandType.move>);
                resultCmd = result.resultCmd;
                checkResult = result.checkResult;
                break;
            }
            case CommandType.attack: {
                const result = this._cmdAttack(cmd as CommandParam<CommandType.attack>);
                resultCmd = result.resultCmd;
                checkResult = result.checkResult;
                break;
            }
            case CommandType.heal: {
                const result = this._cmdHeal(cmd as CommandParam<CommandType.heal>);
                resultCmd = result.resultCmd;
                checkResult = result.checkResult;
                break;
            }
            case CommandType.swap: {
                const result = this._cmdSwap(cmd as CommandParam<CommandType.swap>);
                resultCmd = result.resultCmd;
                checkResult = result.checkResult;
                break;
            }
            case CommandType.build: {
                const result = this._cmdBuild(cmd as CommandParam<CommandType.build>);
                resultCmd = result.resultCmd;
                checkResult = result.checkResult;
                break;
            }
            case CommandType.collect: {
                const result = this._cmdCollect(cmd as CommandParam<CommandType.collect>);
                resultCmd = result.resultCmd;
                checkResult = result.checkResult;
                break;
            }
            case CommandType.end: {
                const result = this._cmdEnd(cmd as CommandParam<CommandType.end>);
                resultCmd = result.resultCmd;
                checkResult = result.checkResult;
                break;
            }
            default:
                this._log('error', 'cmd', '未知命令类型', { "type": cmd.type });
                checkResult = { valid: false, error: '未知命令类型' };
                return { resultCmd: false, checkResult };
        }

        // 如果启用了渲染，将命令传递给战斗场景进行渲染
        if (GameConfig.enableRendering) {
            try {
                // 获取战斗场景实例
                let battleSceneInstance = battleScene.getBattleScene();
                if (checkResult.valid) {
                    battleSceneInstance.handleBattleCommand(resultCmd.type, resultCmd, checkResult);
                } else {
                    // 检验失败时，只显示错误消息到日志面板，不执行mapRenderer
                    if (battleSceneInstance.uiManager) {
                        const position = this.getCommandPosition(resultCmd);
                        battleSceneInstance.showCommandLog(resultCmd, position);
                        const player = this.map.getPlayer(resultCmd.player);
                        const failCount = player ? player.getCommandFailCount() : 0;
                        const errorMessage = `${resultCmd.player}执行失败(${failCount}): ${checkResult.error || '未知错误'}`;
                        battleSceneInstance.uiManager.showMessage(errorMessage, 'error');
                    }
                }
            } catch (e) {
                console.error('调用战斗场景渲染失败:', e);
            }
        }

        return { resultCmd, checkResult };
    }

    /**
     * 初始化命令
     * @param cmd 初始化命令参数
     * @returns 返回包含resultCmd和checkResult的对象
     */
    private _cmdInit(cmd: CommandParam<CommandType.init>): { resultCmd: CommandParam<CommandType.init>; checkResult: { valid: boolean; error?: string } } {
        const commandParam = cmd.param;

        // 根据InitCommandParam类型定义，players已经是string[]类型
        const playerIds = commandParam.players || [];

        // 设置默认地图
        if (!commandParam.map) {
            commandParam.map = 'main';
        }

        const mapData = MapConfigs[commandParam.map];
        // 初始化地图、工厂、校验器
        this.map = new BattleMap(playerIds, mapData, commandParam.map);
        this.factory = new BattleFactory(this.map);
        this.validator = new CommandValidator(this.map);

        // 初始化玩家列表和回合数
        this.players = playerIds;
        this.currentRound = 1; // init后初始化为1

        // 设置最大回合数，如果没有指定则使用默认值
        this.roundLimit = commandParam.round_limit || RoundLimit;

        // 自动为双方玩家创建基地
        this.createPlayerBases(playerIds, commandParam.map);

        // 设置状态为运行中
        this.status = BattleStatus.running;

        return { resultCmd: cmd, checkResult: { valid: true } };
    }

    /**
     * 为双方玩家创建基地
     * @param playerIds 玩家ID列表
     * @param mapType 地图类型
     */
    private createPlayerBases(playerIds: string[], mapType: string): void {
        if (playerIds.length >= 1) {
            // 为玩家1创建基地
            this.factory.createBuilding(playerIds[0], BuildingType.base, BasePositionConfigs[mapType][0]);
        }

        if (playerIds.length >= 2) {
            // 为玩家2创建基地
            this.factory.createBuilding(playerIds[1], BuildingType.base, BasePositionConfigs[mapType][1]);
        }
    }

    /**
     * 计算溅射目标位置
     * @param targetPosition 被攻击目标的位置
     * @param offsetPosition 攻击方向偏移量
     * @returns 溅射目标位置数组
     */
    private calculateSplashPositions(targetPosition: { x: number; y: number }, offsetPosition: { x: number; y: number }): { x: number; y: number }[] {
        // 根据攻击方向计算溅射目标位置
        // 如果攻击方向是(1,0)，则溅射位置是(1,1)和(1,-1)
        // 如果攻击方向是(0,1)，则溅射位置是(1,1)和(-1,1)
        // 如果攻击方向是(-1,0)，则溅射位置是(-1,1)和(-1,-1)
        // 如果攻击方向是(0,-1)，则溅射位置是(1,-1)和(-1,-1)
        const splashPositions: { x: number; y: number }[] = [];

        if (offsetPosition.x !== 0) {
            // 水平攻击，溅射到上下两个位置
            splashPositions.push(
                { x: targetPosition.x, y: targetPosition.y + 1 },
                { x: targetPosition.x, y: targetPosition.y - 1 }
            );
        } else if (offsetPosition.y !== 0) {
            // 垂直攻击，溅射到左右两个位置
            splashPositions.push(
                { x: targetPosition.x + 1, y: targetPosition.y },
                { x: targetPosition.x - 1, y: targetPosition.y }
            );
        }

        return splashPositions;
    }

    /**
     * 处理单位死亡
     * @param killer 击杀者
     * @param victim 死亡的单位
     */
    private handleUnitDeath(killer: UnitModel | BuildingModel, victim: UnitModel): void {
        // 是单位，清除单位ID
        this.map.map[victim.position.y][victim.position.x].unit = null;
        this.map.map[victim.position.y][victim.position.x].player = null;
        this.map.removeUnit(victim.id);
        // 更新击杀统计
        this.updateKillStats(killer, victim, EntityType.unit);
    }

    /**
     * 处理建筑死亡
     * @param killer 击杀者
     * @param victim 死亡的建筑
     */
    private handleBuildingDeath(killer: UnitModel | BuildingModel, victim: BuildingModel): void {
        // 是建筑，如果不是基地则清除建筑ID
        if (victim.type !== BuildingType.base) {
            this.map.map[victim.position.y][victim.position.x].building = null;
            this.map.map[victim.position.y][victim.position.x].player = null;
            this.map.removeBuilding(victim.id);
        }
        // 更新击杀统计
        this.updateKillStats(killer, victim, EntityType.building);
    }

    /**
     * 处理伤害逻辑（包括血量计算、统计更新和死亡处理）
     * @param attacker 攻击者
     * @param target 目标
     * @param damage 伤害值
     */
    private applyDamage(attacker: UnitModel | BuildingModel, target: UnitModel | BuildingModel, damage: number): void {
        // 计算真实伤害量, 对目标造成伤害（血量不能小于0）
        const newHp = Math.max(0, target.hp - damage);
        const actualDamage = target.hp - newHp;

        target.hp = newHp;

        // 更新伤害统计（使用真实伤害量）
        this.updateDamageStats(attacker, target, actualDamage);

        // 如果目标死亡，从地图中移除并更新击杀统计
        if (target.hp <= 0) {
            // 判断目标类型
            if (this.map.getTildeAt(target.position).unit) {
                this.handleUnitDeath(attacker, target as UnitModel);
            } else if (this.map.getTildeAt(target.position).building) {
                this.handleBuildingDeath(attacker, target as BuildingModel);
            }
        }
    }

    /**
     * 处理溅射伤害逻辑
     * @param attacker 攻击者
     * @param targeter 目标单位
     * @param offsetPosition 攻击方向偏移量
     */
    private applySplashDamage(attacker: UnitModel | BuildingModel, targeter: UnitModel | BuildingModel, offsetPosition: { x: number; y: number }): void {
        const splashDamage = Math.floor(attacker.attack * SplashDamageRatio);

        // 计算溅射目标位置
        const splashPositions = this.calculateSplashPositions(targeter.position, offsetPosition);

        // 对溅射位置的敌方单位造成伤害
        for (const splashPos of splashPositions) {
            // 检查位置是否在地图范围内
            if (!this.map.isPositionInBounds(splashPos)) {
                continue;
            }
            const splashUnit = this.map.getUnitAt(splashPos);
            // 检查是否有单位在溅射到的位置
            if (!splashUnit) {
                continue;
            }
            // 只对敌方单位造成溅射伤害
            if (splashUnit.player === attacker.player) {
                continue;
            }

            // 对溅射目标造成伤害
            this.applyDamage(attacker, splashUnit, splashDamage);
        }
    }

    /**
     * 更新攻击后的单位/建筑状态
     * @param self 攻击者
     * @param target 被攻击者
     * @param offsetPosition 攻击方向偏移量
     */
    private updateAttack(self: UnitModel | BuildingModel, target: UnitModel | BuildingModel, offsetPosition: { x: number; y: number }) {

        // 在造成伤害前，先检查是否需要溅射伤害（士兵攻击单位时）
        const shouldApplySplash = self.type === UnitType.soldier && this.map.getTildeAt(target.position).unit;

        // 对目标造成伤害
        this.applyDamage(self, target, self.attack);

        // 士兵攻击单位时的溅射伤害（仅对敌方单位有效）
        // 注意：即使目标在主要攻击中死亡，溅射伤害仍然应该生效
        if (shouldApplySplash) {
            this.applySplashDamage(self, target, offsetPosition);
        }

    }

    /**
     * 攻击命令
     * @param cmd 攻击命令参数
     * @returns 返回修改后的命令对象或false（如果失败）
     */
    private _cmdAttack(cmd: CommandParam<CommandType.attack>): { resultCmd: CommandParam<CommandType.attack>; checkResult: { valid: boolean; error?: string } } {
        // 检查模块
        const checkResult = this.validator.checkAttack(cmd);
        if (!checkResult.valid) {
            const errorMsg = `攻击命令检查失败: ${checkResult.error}`;
            // 记录失败命令
            this.recordFailedCommand(cmd, errorMsg);
            return { resultCmd: cmd, checkResult };
        }

        let param = cmd.param;
        let self: UnitModel | BuildingModel;
        if (param.self.type === EntityType.unit) {
            self = this.map.getUnit(param.self.id);
        } else if (param.self.type === EntityType.building) {
            self = this.map.getBuilding(param.self.id);
        }

        let target: UnitModel | BuildingModel;
        if (param.target.type === EntityType.unit) {
            target = this.map.getUnit(param.target.id);
        } else if (param.target.type === EntityType.building) {
            target = this.map.getBuilding(param.target.id);
        }

        // 更新模块
        this.updateAttack(self, target, param.offsetPosition);

        return { resultCmd: cmd, checkResult };
    }

    /**
     * 更新生产单位后的状态
     * @param cmd 生产单位命令
     * @returns 生产的单位ID
     */
    private updateSwap(cmd: CommandParam<CommandType.swap>) {
        const swapParam = cmd.param;

        // 获取建筑位置
        let building = this.map.getBuilding(swapParam.self.id);
        if (!building) return;

        // 计算生产位置（基地位置+偏移量）
        let targetPosition = {
            x: building.position.x + swapParam.offsetPosition.x,
            y: building.position.y + swapParam.offsetPosition.y,
        };

        // 扣除玩家资源
        const unitType = swapParam.target.utype as UnitType;
        const unitCost = UnitConfig[unitType].cost;

        const player = this.map.getPlayer(cmd.player);

        player.addRmb(-unitCost);

        // 创建新单位
        let unit = this.factory.createUnit(cmd.player, unitType, targetPosition);

        // 更新命令中的目标信息
        if (swapParam.target) {
            swapParam.target.id = unit.id;
        }

        // 记录新生产的单位到当前回合新实体集合
        const newEntityKey = `${cmd.round}-${cmd.player}-${EntityType.unit}-${unit.id}`;
        this.currentRoundNewEntities.add(newEntityKey);

    }

    /**
     * 生产单位命令
     * @param cmd 交换命令参数
     * @returns 返回包含resultCmd和checkResult的对象
     */
    private _cmdSwap(cmd: CommandParam<CommandType.swap>): { resultCmd: CommandParam<CommandType.swap>; checkResult: { valid: boolean; error?: string } } {
        // 检查模块
        const checkResult = this.validator.checkSwap(cmd);
        if (!checkResult.valid) {
            const errorMsg = `生产命令检查失败: ${checkResult.error}`;
            this._log('error', 'cmd_swap', errorMsg, cmd );
            // 记录失败命令
            this.recordFailedCommand(cmd, errorMsg);
            return { resultCmd: cmd, checkResult };
        }

        // 更新模块
        this.updateSwap(cmd);

        return { resultCmd: cmd, checkResult };
    }

    /**
     * 更新地图和单位状态
     * @param cmd 移动命令
     * @returns 单位的新位置
     */
    private updateMoveTo(cmd: CommandParam<CommandType.move>) {
        const moveParam = cmd.param;
        let unit = this.map.getUnit(moveParam.self.id);
        if (!unit) return;
        let offsetPosition = moveParam.offsetPosition;

        // 计算新的绝对位置（基于位置差值）
        let newPosition = {
            x: unit.position.x + offsetPosition.x,
            y: unit.position.y + offsetPosition.y,
        };

        // 清除原位置的单位
        this.map.map[unit.position.y][unit.position.x].unit = null;
        this.map.map[unit.position.y][unit.position.x].player = null;

        // 在新位置放置单位
        this.map.map[newPosition.y][newPosition.x].unit = unit.id;
        this.map.map[newPosition.y][newPosition.x].player = unit.player;

        // 更新单位位置
        unit.position = newPosition;
    }

    /**
     * 移动单位命令
     * @param cmd 移动命令参数
     * @returns 返回包含resultCmd和checkResult的对象
     */
    private _cmdMoveTo(cmd: CommandParam<CommandType.move>): { resultCmd: CommandParam<CommandType.move>; checkResult: { valid: boolean; error?: string } } {
        // 检查模块
        const checkResult = this.validator.checkMoveTo(cmd);
        if (!checkResult.valid) {
            const errorMsg = `移动命令检查失败: ${checkResult.error}`;
            this._log('error', 'cmd_move', errorMsg, cmd );
            // 记录失败命令
            this.recordFailedCommand(cmd, errorMsg);
            return { resultCmd: cmd, checkResult };
        }

        // 更新模块
        this.updateMoveTo(cmd);

        return { resultCmd: cmd, checkResult };
    }

    /**
     * 更新建造后的状态
     * @param cmd 建造命令
     * @returns 建造的建筑ID
     */
    private updateBuild(cmd: CommandParam<CommandType.build>) {
        let param = cmd.param;
        const buildingType = param.target.utype;

        // 获取建造者单位
        let unit = this.map.getUnit(param.self.id);
        let targetPosition;

        // 如果是建造基地，直接使用偏移位置作为绝对位置
        if (buildingType === BuildingType.base) {
            targetPosition = {
                x: param.offsetPosition.x,
                y: param.offsetPosition.y,
            };
        } else {
            // 对于其他建筑，需要建造者单位
            if (!unit) return;

            // 计算建造位置（建造者位置+偏移量）
            targetPosition = {
                x: unit.position.x + param.offsetPosition.x,
                y: unit.position.y + param.offsetPosition.y,
            };
        }

        // 扣除玩家资源
        const buildingCost = BuildingConfig[buildingType].cost;
        this.map.getPlayer(cmd.player).addRmb(-buildingCost);

        // 创建建筑
        const building = this.factory.createBuilding(cmd.player, buildingType, targetPosition);

        // 更新命令中的目标信息
        if (param.target) {
            param.target.id = building.id;
        }

        // 记录新建造的建筑到当前回合新实体集合
        const newEntityKey = `${cmd.round}-${cmd.player}-${EntityType.building}-${building.id}`;
        this.currentRoundNewEntities.add(newEntityKey);

    }

    /**
     * 建造建筑命令
     * @param cmd 建造命令参数
     * @returns 返回包含resultCmd和checkResult的对象
     */
    private _cmdBuild(cmd: CommandParam<CommandType.build>): { resultCmd: CommandParam<CommandType.build>; checkResult: { valid: boolean; error?: string } } {
        // 检查模块
        const checkResult = this.validator.checkBuild(cmd);
        if (!checkResult.valid) {
            const errorMsg = `建造命令检查失败: ${checkResult.error}`;
            this._log('error', 'cmd_build', errorMsg, cmd );
            // 记录失败命令
            this.recordFailedCommand(cmd, errorMsg);
            return { resultCmd: cmd, checkResult };
        }

        // 更新模块
        this.updateBuild(cmd);

        return { resultCmd: cmd, checkResult };
    }

    /**
     * 更新治疗后的单位状态
     * @param self 治疗者
     * @param target 被治疗者
     */
    private updateHeal(self: UnitModel, target: UnitModel): void {
        const healAmount = self.attack;
        const originalHp = target.hp;

        // 对目标进行治疗，不能超过最大血量
        const maxHp = UnitConfig[target.type].hp;
        target.hp = Math.min(target.hp + healAmount, maxHp);

        // 计算实际治疗量
        const actualHealAmount = target.hp - originalHp;

        // 更新治疗统计
        this.updateHealingStats(self, actualHealAmount);
    }

    /**
     * 执行治疗命令
     * @param cmd 治疗命令
     * @returns 返回包含resultCmd和checkResult的对象
     */
    private _cmdHeal(cmd: CommandParam<CommandType.heal>): { resultCmd: CommandParam<CommandType.heal>; checkResult: { valid: boolean; error?: string } } {
        // 检查模块
        const checkResult = this.validator.checkHeal(cmd);
        if (!checkResult.valid) {
            const errorMsg = `治疗命令检查失败: ${checkResult.error}`;
            this._log('error', 'cmd_heal', errorMsg, cmd );
            // 记录失败命令
            this.recordFailedCommand(cmd, errorMsg);
            return { resultCmd: cmd, checkResult };
        }

        let param = cmd.param;
        let self = this.map.getUnit(param.self.id);
        let target = this.map.getUnit(param.target.id);

        // 更新模块
        this.updateHeal(self, target);

        return { resultCmd: cmd, checkResult }; // 返回命令对象
    }

    /**
     * 更新采集资源后的状态
     * @param cmd 采集命令
     * @returns 采集的资源信息
     */
    private updateCollect(cmd: CommandParam<CommandType.collect>): { targetPosition: { x: number; y: number }; resourceType: number; resourceValue: number } {
        let param = cmd.param;
        let self = this.map.getUnit(param.self.id);
        // 计算目标位置
        let targetX = self.position.x + param.offsetPosition.x;
        let targetY = self.position.y + param.offsetPosition.y;
        let targetPosition = { x: targetX, y: targetY };
        // 获取目标位置的地形类型
        let resourceType = this.map.map[targetY][targetX].type;

        // 从ResourceConfig获取资源价值
        const resourceValue = ResourceConfig[resourceType].value;

        // 获取玩家并添加资源
        const player = this.map.getPlayer(self.player);
        player.addRmb(resourceValue);

        return { targetPosition, resourceType, resourceValue };
    }

    /**
     * 采集命令
     * @param cmd 采集命令参数
     * @returns 返回包含resultCmd和checkResult的对象
     */
    private _cmdCollect(cmd: CommandParam<CommandType.collect>): { resultCmd: CommandParam<CommandType.collect>; checkResult: { valid: boolean; error?: string } } {
        // 检查采集命令是否有效
        const checkResult = this.validator.checkCollect(cmd);
        if (!checkResult.valid) {
            const errorMsg = `采集命令检查失败: ${checkResult.error}`;
            this._log('error', 'cmd_collect', errorMsg, cmd);
            // 记录失败命令
            this.recordFailedCommand(cmd, errorMsg);
            return { resultCmd: cmd, checkResult };
        }

        // 更新模块
        this.updateCollect(cmd);

        return { resultCmd: cmd, checkResult };
    }

    /**
     * 结束命令
     * @param cmd 结束命令参数
     * @returns 返回包含resultCmd和checkResult的对象
     */
    private _cmdEnd(cmd: CommandParam<CommandType.end>): { resultCmd: CommandParam<CommandType.end>; checkResult: { valid: boolean; error?: string } } {

        return { resultCmd: cmd, checkResult: { valid: true } };
    }

    /**
     * 更新伤害统计
     * @param attacker 攻击者
     * @param target 被攻击者
     * @param damage 伤害值
     */
    private updateDamageStats(attacker: UnitModel | BuildingModel, target: UnitModel | BuildingModel, damage: number): void {
        // 更新攻击者的造成伤害统计
        const attackerPlayer = this.map.getPlayer(attacker.player);
        if (attackerPlayer) {
            attackerPlayer.addDamageDealt(damage);
        }

        // 更新被攻击者的受到伤害统计
        const targetPlayer = this.map.getPlayer(target.player);
        if (targetPlayer) {
            targetPlayer.addDamageReceived(damage);
        }
    }

    /**
     * 更新击杀统计
     * @param killer 击杀者
     * @param victim 被击杀者
     */
    private updateKillStats(killer: UnitModel | BuildingModel, victim: UnitModel | BuildingModel, victimType: EntityType): void {
        // 更新击杀者的击杀数
        const killerPlayer = this.map.getPlayer(killer.player);
        if (killerPlayer) {
            killerPlayer.addKill();
        }

        // 更新被击杀者的死亡数
        const victimPlayer = this.map.getPlayer(victim.player);
        if (victimPlayer) {
            victimPlayer.addDeath();
        }

        // 给击杀方增加击杀奖励
        if (killerPlayer) {
            let killReward = 0;

            // 根据被击杀目标类型获取击杀奖励
            if (victimType === EntityType.unit) {
                // 被击杀的是单位
                const unitConfig = UnitConfig[victim.type as UnitType];
                if (unitConfig && unitConfig.killedAward) {
                    killReward = unitConfig.killedAward;
                }
            } else if (victimType === EntityType.building) {
                // 被击杀的是建筑
                const buildingConfig = BuildingConfig[victim.type as BuildingType];
                if (buildingConfig && buildingConfig.killedAward) {
                    killReward = buildingConfig.killedAward;
                }
            }

            // 增加击杀奖励
            if (killReward > 0) {
                killerPlayer.addRmb(killReward);
            }
        }
    }

    /**
     * 更新治疗统计
     * @param healer 治疗者
     * @param healAmount 治疗量
     */
    private updateHealingStats(healer: UnitModel | BuildingModel, healAmount: number) {
        const healerPlayer = this.map.getPlayer(healer.player);
        if (healerPlayer) {
            healerPlayer.addHealing(healAmount);
        }
    }

    /**
     * 获取玩家统计数据
     * @param player 玩家ID，如果不提供则返回所有玩家的统计
     * @returns 玩家统计数据
     */
    public getPlayerStats(player?: string): PlayerStatsModel | PlayerStatsModel[] {
        if (player) {
            const playerObj = this.map.getPlayer(player);
            if (!playerObj) return null;

            return {
                player: player,
                totalDamageDealt: playerObj.getTotalDamageDealt(),
                totalDamageReceived: playerObj.getTotalDamageReceived(),
                totalHealing: playerObj.getTotalHealing(),
                kills: playerObj.getKills(),
                deaths: playerObj.getDeaths(),
                rmb: playerObj.getRmb(),
                commandFailCount: playerObj.getCommandFailCount(),
                baseHealth: playerObj.getBaseHealth(),
            };
        }

        // 返回所有玩家的统计数据
        return this.map.getAllPlayers().map((p) => ({
            player: p.getId(),
            totalDamageDealt: p.getTotalDamageDealt(),
            totalDamageReceived: p.getTotalDamageReceived(),
            totalHealing: p.getTotalHealing(),
            kills: p.getKills(),
            deaths: p.getDeaths(),
            rmb: p.getRmb(),
            commandFailCount: p.getCommandFailCount(),
            baseHealth: p.getBaseHealth(),
        }));
    }

    /**
     * 检查玩家是否因无实体且经济不足而败北
     * 当玩家的单位和非基地建筑数量为0且总资源经济不满足构建价值最低的单位或非基地建筑时，判负
     * @param playerId 玩家ID
     * @returns 是否败北
     */
    private checkPlayerEconomicDefeat(playerId: string): boolean {
        const player = this.map.getPlayer(playerId);
        if (!player) return false;

        // 获取玩家的所有单位和建筑
        const units = player.getAllUnits();
        const buildings = player.getAllBuildings();

        // 过滤出非基地建筑
        const nonBaseBuildings = buildings.filter(building => building.type !== BuildingType.base);

        // 如果玩家还有单位或非基地建筑，则不败北
        if (units.length > 0 || nonBaseBuildings.length > 0) {
            return false;
        }

        // 获取玩家当前资源
        const currentRmb = player.getRmb();

        // 计算最便宜的单位成本
        const cheapestUnitCost = Math.min(
            UnitConfig[UnitType.soldier].cost,
            UnitConfig[UnitType.collect].cost,
            UnitConfig[UnitType.doctor].cost,
            UnitConfig[UnitType.archer].cost,
            UnitConfig[UnitType.worker].cost
        );

        // 计算最便宜的非基地建筑成本
        const cheapestBuildingCost = Math.min(
            BuildingConfig[BuildingType.tower].cost,
            BuildingConfig[BuildingType.wall].cost
        );

        // 计算最便宜的可构建实体成本
        const cheapestEntityCost = Math.min(cheapestUnitCost, cheapestBuildingCost);

        // 如果当前资源不足以构建最便宜的实体，则败北
        return currentRmb < cheapestEntityCost;
    }

    /**
     * 每回合胜负判定
     */
    private checkBattleResult(): boolean {
        // 获取所有基地
        const bases = this.map.getAllBuildings().filter((b) => b.type === BuildingType.base);
        if (bases.length < 2) return false; // 基地未全部建造

        // 获取战斗统计数据，供后续使用
        const playerStats = this.getPlayerStats() as PlayerStatsModel[];
        const playerStatsMap: {[key: string]: PlayerStatsModel} = {};
        playerStats.forEach((stat) => {
            playerStatsMap[stat.player] = stat;
        });

        // 1.代码执行异常次数判定
        const playersOverCodeFailLimit = playerStats.filter(stat => {
            const playerObj = this.map.getPlayer(stat.player);
            return playerObj && playerObj.getCodeExecutionFailCount() >= CodeExecutionFailLimit;
        });
        // 如果只有一个玩家超过代码执行异常次数限制，直接判负
        if (playersOverCodeFailLimit.length === 1) {
            const loser = playersOverCodeFailLimit[0].player;
            const winner = this.players.find((p) => p !== loser);

            // 收集所有玩家的失败命令
            const failedCommandsMap: {[key: string]: FailCommandModel[]} = {};
            this.players.forEach((playerId) => {
                const player = this.map.getPlayer(playerId);
                if (player) {
                    failedCommandsMap[playerId] = player.getFailedCommands();
                }
            });

            // 创建战斗结果数据
            const battleResult: BattleResultData = {
                winner: winner,
                loser: loser,
                msg: `玩家${loser}代码执行异常次数达到上限(${CodeExecutionFailLimit}次)，自动判负，战斗结束！`,
                playerStats: playerStatsMap,
                failedCommands: failedCommandsMap,
            };

            // 缓存战斗结果
            this.battleResult = battleResult;

            return true;
        }
        // 如果双方都超过代码执行异常次数限制，需要通过其他条件判定胜负
        const shouldEndByCodeFailCount = playersOverCodeFailLimit.length >= 2;

        // 2.命令失败次数判定
        const playersOverFailLimit = playerStats.filter(stat => {
            const playerObj = this.map.getPlayer(stat.player);
            return playerObj.getCommandFailCount() >= CommandFailLimit;
        });
        // 如果只有一个玩家超过失败次数限制，直接判负
        if (playersOverFailLimit.length === 1) {
            const loser = playersOverFailLimit[0].player;
            const winner = this.players.find((p) => p !== loser);

            // 收集所有玩家的失败命令
            const failedCommandsMap: {[key: string]: FailCommandModel[]} = {};
            this.players.forEach((playerId) => {
                const player = this.map.getPlayer(playerId);
                if (player) {
                    failedCommandsMap[playerId] = player.getFailedCommands();
                }
            });

            // 创建战斗结果数据
            const battleResult: BattleResultData = {
                winner: winner,
                loser: loser,
                msg: `玩家${loser}的命令失败次数达到${CommandFailLimit}次，战斗结束！`,
                playerStats: playerStatsMap,
                failedCommands: failedCommandsMap,
            };

            // 缓存战斗结果
            this.battleResult = battleResult;

            return true;
        }
        // 如果双方都超过失败次数限制，需要通过其他条件判定胜负
        const shouldEndByFailCount = playersOverFailLimit.length >= 2;

        // 3.基地血量为0判定
        const deadBases = bases.filter((b) => b.hp <= 0);
        // 如果只有一个基地被摧毁，直接判负
        if (deadBases.length === 1) {
            const loser = deadBases[0].player;
            const winner = this.players.find((p) => p !== loser);

            // 收集所有玩家的失败命令
            const failedCommandsMap: {[key: string]: FailCommandModel[]} = {};
            this.players.forEach((playerId) => {
                const player = this.map.getPlayer(playerId);
                if (player) {
                    failedCommandsMap[playerId] = player.getFailedCommands();
                }
            });

            // 创建战斗结果数据
            const battleResult: BattleResultData = {
                winner: winner,
                loser: loser,
                msg: `玩家<${deadBases[0].player}>的基地被摧毁，战斗结束！`,
                playerStats: playerStatsMap,
                failedCommands: failedCommandsMap,
            };

            // 缓存战斗结果
            this.battleResult = battleResult;

            return true;
        }
        // 如果双方基地都被摧毁，需要通过其他条件判定胜负
        const shouldEndByBaseDeath = deadBases.length >= 2;

        // 4.无实体无经济败北判定
        const economicDefeatPlayers = this.players.filter(playerId => this.checkPlayerEconomicDefeat(playerId));
        // 如果只有一个玩家无实体无经济败北，直接判负
        if (economicDefeatPlayers.length === 1) {
            const loser = economicDefeatPlayers[0];
            const winner = this.players.find((p) => p !== loser);

            // 收集所有玩家的失败命令
            const failedCommandsMap: {[key: string]: FailCommandModel[]} = {};
            this.players.forEach((playerId) => {
                const player = this.map.getPlayer(playerId);
                if (player) {
                    failedCommandsMap[playerId] = player.getFailedCommands();
                }
            });

            // 创建战斗结果数据
            const battleResult: BattleResultData = {
                winner: winner,
                loser: loser,
                msg: `玩家<${loser}>无单位和非基地建筑且资源不足以构建任何实体，战斗结束！`,
                playerStats: playerStatsMap,
                failedCommands: failedCommandsMap,
            };

            // 缓存战斗结果
            this.battleResult = battleResult;

            return true;
        }
        // 如果双方都无实体无经济败北，需要通过其他条件判定胜负
        const shouldEndByEconomicDefeat = economicDefeatPlayers.length >= 2;

        // 5.满回合判定
        if (this.currentRound >= this.roundLimit || shouldEndByCodeFailCount || shouldEndByFailCount || shouldEndByBaseDeath || shouldEndByEconomicDefeat) {
            const [base1, base2] = bases;
            let winner = null;
            let loser = null;
            let msg = '';

            let endReason = '';
            if (shouldEndByBaseDeath) {
                endReason = '双方基地都被摧毁';
            } else if (shouldEndByCodeFailCount) {
                endReason = '双方代码执行异常次数都达到限制, 且双方基地均未摧毁';
            } else if (shouldEndByFailCount) {
                endReason = '双方命令失败次数都达到限制, 且双方基地均未摧毁';
            } else if (shouldEndByEconomicDefeat) {
                endReason = '双方无实体无经济都败北, 且双方基地均未摧毁';
            } else {
                endReason = `达到${this.roundLimit}回合, 且双方基地均未摧毁`;
            }

            // 根据战斗统计数据决定胜负
            const stats1 = playerStatsMap[base1.player];
            const stats2 = playerStatsMap[base2.player];

            if (stats1 && stats2) {
                // 获取玩家对象以获取更多统计数据
                const player1 = this.map.getPlayer(base1.player);
                const player2 = this.map.getPlayer(base2.player);

                // 计算存活数量（单位+建筑）
                const aliveCount1 = player1 ? player1.getAliveUnitsCount() + player1.getExistingBuildingsCount() : 0;
                const aliveCount2 = player2 ? player2.getAliveUnitsCount() + player2.getExistingBuildingsCount() : 0;

                // 计算剩余实体血量总和（单位+建筑）
                const totalRemainingHp1 = player1 ?
                    player1.getAllUnits().reduce((sum, unit) => sum + unit.hp, 0) +
                    player1.getAllBuildings().reduce((sum, building) => sum + building.hp, 0) : 0;
                const totalRemainingHp2 = player2 ?
                    player2.getAllUnits().reduce((sum, unit) => sum + unit.hp, 0) +
                    player2.getAllBuildings().reduce((sum, building) => sum + building.hp, 0) : 0;

                // 优先级：基地血量 > 击杀数量 > 造成伤害 > 存活数 > 剩余实体血量总和 > 治疗量 > 经济值 > 命令失败数
                if (base1.hp !== base2.hp) {
                    if (base1.hp > base2.hp) {
                        winner = base1.player;
                        loser = base2.player;
                        msg = `${endReason}，玩家<${base2.player}>基地血量更低，失败！`;
                    } else if (base2.hp > base1.hp) {
                        winner = base2.player;
                        loser = base1.player;
                        msg = `${endReason}，玩家<${base1.player}>基地血量更低，失败！`;
                    }
                } else if (stats1.kills !== stats2.kills) {
                    if (stats1.kills > stats2.kills) {
                        winner = base1.player;
                        loser = base2.player;
                        msg = `${endReason}，玩家<${base1.player}>击杀数更多(${stats1.kills} vs ${stats2.kills})，获胜！`;
                    } else {
                        winner = base2.player;
                        loser = base1.player;
                        msg = `${endReason}，玩家<${base2.player}>击杀数更多(${stats2.kills} vs ${stats1.kills})，获胜！`;
                    }
                } else if (stats1.totalDamageDealt !== stats2.totalDamageDealt) {
                    if (stats1.totalDamageDealt > stats2.totalDamageDealt) {
                        winner = base1.player;
                        loser = base2.player;
                        msg = `${endReason}，击杀数相同，玩家<${base1.player}>造成伤害更高(${stats1.totalDamageDealt} vs ${stats2.totalDamageDealt})，获胜！`;
                    } else {
                        winner = base2.player;
                        loser = base1.player;
                        msg = `${endReason}，击杀数相同，玩家<${base2.player}>造成伤害更高(${stats2.totalDamageDealt} vs ${stats1.totalDamageDealt})，获胜！`;
                    }
                } else if (aliveCount1 !== aliveCount2) {
                    if (aliveCount1 > aliveCount2) {
                        winner = base1.player;
                        loser = base2.player;
                        msg = `${endReason}，击杀造成伤害相同，玩家<${base1.player}>存活数更多(${aliveCount1} vs ${aliveCount2})，获胜！`;
                    } else {
                        winner = base2.player;
                        loser = base1.player;
                        msg = `${endReason}，击杀造成伤害相同，玩家<${base2.player}>存活数更多(${aliveCount2} vs ${aliveCount1})，获胜！`;
                    }
                } else if (totalRemainingHp1 !== totalRemainingHp2) {
                    if (totalRemainingHp1 > totalRemainingHp2) {
                        winner = base1.player;
                        loser = base2.player;
                        msg = `${endReason}，击杀造成伤害存活数相同，玩家<${base1.player}>剩余实体血量总和更高(${totalRemainingHp1} vs ${totalRemainingHp2})，获胜！`;
                    } else {
                        winner = base2.player;
                        loser = base1.player;
                        msg = `${endReason}，击杀造成伤害存活数相同，玩家<${base2.player}>剩余实体血量总和更高(${totalRemainingHp2} vs ${totalRemainingHp1})，获胜！`;
                    }
                } else if (stats1.totalHealing !== stats2.totalHealing) {
                    if (stats1.totalHealing > stats2.totalHealing) {
                        winner = base1.player;
                        loser = base2.player;
                        msg = `${endReason}，击杀造成伤害存活数剩余血量相同，玩家<${base1.player}>治疗量更高(${stats1.totalHealing} vs ${stats2.totalHealing})，获胜！`;
                    } else {
                        winner = base2.player;
                        loser = base1.player;
                        msg = `${endReason}，击杀造成伤害存活数剩余血量相同，玩家<${base2.player}>治疗量更高(${stats2.totalHealing} vs ${stats1.totalHealing})，获胜！`;
                    }
                } else if (stats1.rmb !== stats2.rmb) {
                    if (stats1.rmb > stats2.rmb) {
                        winner = base1.player;
                        loser = base2.player;
                        msg = `${endReason}，击杀造成伤害存活数剩余血量治疗量相同，玩家<${base1.player}>经济值更高(${stats1.rmb} vs ${stats2.rmb})，获胜！`;
                    } else {
                        winner = base2.player;
                        loser = base1.player;
                        msg = `${endReason}，击杀造成伤害存活数剩余血量治疗量相同，玩家<${base2.player}>经济值更高(${stats2.rmb} vs ${stats1.rmb})，获胜！`;
                    }
                } else if (stats1.commandFailCount !== stats2.commandFailCount) {
                    if (stats1.commandFailCount < stats2.commandFailCount) {
                        winner = base1.player;
                        loser = base2.player;
                        msg = `${endReason}，击杀造成伤害存活数剩余血量治疗量经济值相同，玩家<${base1.player}>失败命令数更少(${stats1.commandFailCount} vs ${stats2.commandFailCount})，获胜！`;
                    } else {
                        winner = base2.player;
                        loser = base1.player;
                        msg = `${endReason}，击杀造成伤害存活数剩余血量治疗量经济值相同，玩家<${base2.player}>失败命令数更少(${stats2.commandFailCount} vs ${stats1.commandFailCount})，获胜！`;
                    }
                } else {
                    // 所有数据都相同时，默认左边玩家（base2.player）获胜
                    winner = base2.player;
                    loser = base1.player;
                    msg = `${endReason}，所有战斗数据相同，默认玩家<${base2.player}>获胜！`;
                }
            } else {
                // 无法获取统计数据时，默认右边玩家（base2.player）获胜
                winner = base2.player;
                loser = base1.player;
                msg = `${endReason}，默认玩家<${base2.player}>获胜！`;
            }


            // 收集所有玩家的失败命令
            const failedCommandsMap: {[key: string]: FailCommandModel[]} = {};
            this.players.forEach((playerId) => {
                const player = this.map.getPlayer(playerId);
                if (player) {
                    failedCommandsMap[playerId] = player.getFailedCommands();
                }
            });

            // 创建战斗结果数据
            const battleResult: BattleResultData = {
                winner: winner,
                loser: loser,
                msg: msg,
                playerStats: playerStatsMap,
                failedCommands: failedCommandsMap,
            };

            // 缓存战斗结果
            this.battleResult = battleResult;

            return true;
        }

        return false;
    }

    /**
     * 获取命令执行位置
     * @param cmd 命令参数
     * @returns 命令执行的位置坐标，如果无法计算则返回undefined
     */
    private getCommandPosition(cmd: CommandParam<keyof CommandParamMap>): { x: number; y: number } | undefined {
        let position: { x: number; y: number } | undefined = undefined;

        if (cmd.type === CommandType.move) {
            const moveParam = (cmd as CommandParam<CommandType.move>).param;
            const unit = this.map.getUnit(moveParam.self.id);
            if (unit) {
                position = {
                    x: unit.position.x + moveParam.offsetPosition.x,
                    y: unit.position.y + moveParam.offsetPosition.y
                };
            }
        } else if (cmd.type === CommandType.build) {
            const buildParam = (cmd as CommandParam<CommandType.build>).param;
            const buildingType = buildParam.target.utype;

            if (buildingType === BuildingType.base) {
                // 基地直接使用偏移位置作为绝对位置
                position = {
                    x: buildParam.offsetPosition.x,
                    y: buildParam.offsetPosition.y
                };
            } else {
                // 其他建筑需要建造者位置+偏移量
                const unit = this.map.getUnit(buildParam.self.id);
                if (unit) {
                    position = {
                        x: unit.position.x + buildParam.offsetPosition.x,
                        y: unit.position.y + buildParam.offsetPosition.y
                    };
                }
            }
        } else if (cmd.type === CommandType.swap) {
            const swapParam = (cmd as CommandParam<CommandType.swap>).param;
            const building = this.map.getBuilding(swapParam.self.id);
            if (building) {
                position = {
                    x: building.position.x + swapParam.offsetPosition.x,
                    y: building.position.y + swapParam.offsetPosition.y
                };
            }
        } else if (cmd.type === CommandType.attack) {
            const attackParam = (cmd as CommandParam<CommandType.attack>).param;
            const attacker = this.map.getUnit(attackParam.self.id) || this.map.getBuilding(attackParam.self.id);
            if (attacker) {
                // 攻击命令使用攻击者位置+偏移量
                position = {
                    x: attacker.position.x + attackParam.offsetPosition.x,
                    y: attacker.position.y + attackParam.offsetPosition.y
                };
            }
        } else if (cmd.type === CommandType.heal) {
            const healParam = (cmd as CommandParam<CommandType.heal>).param;
            const healer = this.map.getUnit(healParam.self.id);
            if (healer) {
                // 治疗命令使用治疗者位置+偏移量
                position = {
                    x: healer.position.x + healParam.offsetPosition.x,
                    y: healer.position.y + healParam.offsetPosition.y
                };
            }
        } else if (cmd.type === CommandType.collect) {
            const collectParam = (cmd as CommandParam<CommandType.collect>).param;
            const collector = this.map.getUnit(collectParam.self.id);
            if (collector) {
                // 采集命令使用采集目标位置（采集者位置+偏移量）
                position = {
                    x: collector.position.x + collectParam.offsetPosition.x,
                    y: collector.position.y + collectParam.offsetPosition.y
                };
            }
        }

        return position;
    }

    /**
     * 记录失败命令的统一方法
     * @param cmd 失败的命令
     * @param error 错误信息
     */
    private recordFailedCommand(cmd: CommandParam<keyof CommandParamMap>, notValidMsg: string): void {
        const player = this.map.getPlayer(cmd.player);
        if (player) {
            player.addFailedCommand({
                error: notValidMsg,
                command: cmd,
                player: cmd.player,
                round: cmd.round,
                type: cmd.type,
            });
        }
    }

    /**
     * 记录命令执行详情
     * @param cmd 命令
     * @param isError 是否执行失败
     * @param error 错误信息
     */
    /**
     * 根据实体类型和子类型获取实体名称
     */
    private getEntityName(entityType: EntityType, utype: UnitType | BuildingType | TildeType): string {
        switch (entityType) {
            case EntityType.unit:
                return getUnitConfig(utype as UnitType)?.name || '未知单位';
            case EntityType.building:
                return getBuildingConfig(utype as BuildingType)?.name || '未知建筑';
            case EntityType.terrain:
                return TERRAIN_NAMES[utype as TildeType] || '未知地形';
            default:
                return '未知实体';
        }
    }

    private recordCommandExecutionDetail(
        cmd: CommandParam<keyof CommandParamMap>,
        valid: boolean,
        notValidMsg: string = '',
    ): CommandExecutionDetailModel {

        let selfState: EntityExecutionState | undefined;
        let targetState: EntityExecutionState | undefined;

        const detail: CommandExecutionDetailModel = {
            command: cmd,
            player: cmd.player,
            round: cmd.round,
            type: cmd.type,
            selfExecutionState: selfState,
            targetExecutionState: targetState,
            isError: !valid,
            error: notValidMsg
        };

        if (!cmd.param) {
            return detail;
        }

        let param = cmd.param

        // 获取self实体状态
        if ('self' in param && param.self) {
            let selfEntity: UnitModel | BuildingModel | undefined;
            if (param.self.type === EntityType.unit) {
                selfEntity = this.map.getUnit(param.self.id);
            } else if (param.self.type === EntityType.building) {
                selfEntity = this.map.getBuilding(param.self.id);
            }
            if (selfEntity) {
                selfState = {
                    id: selfEntity.id,
                    name: this.getEntityName(param.self.type, selfEntity.type),
                    position: { x: selfEntity.position.x, y: selfEntity.position.y },
                    hp: selfEntity.hp
                };
            }
        }

        // 获取target实体状态
        if ('target' in param && param.target) {
            let targetEntity: UnitModel | BuildingModel | undefined;
            if (param.target.type === EntityType.unit) {
                targetEntity = this.map.getUnit(param.target.id);
            } else if (param.target.type === EntityType.building) {
                targetEntity = this.map.getBuilding(param.target.id);
            }
            if (targetEntity) {
                targetState = {
                    id: targetEntity.id,
                    name: this.getEntityName(param.target.type, targetEntity.type),
                    position: { x: targetEntity.position.x, y: targetEntity.position.y },
                    hp: targetEntity.hp
                };
            }
        }

        detail.selfExecutionState = selfState;
        detail.targetExecutionState = targetState;

        return detail;
    }

    /**
     * 检查战斗是否正在进行
     */
    public isBattleRunning(): boolean {
        return this.status === BattleStatus.running;
    }

    /**
     * 检查战斗是否已结束
     */
    public isBattleEnded(): boolean {
        return this.status === BattleStatus.end;
    }

    /**
     * 获取当前回合数
     */
    public getCurrentRound(): number {
        return this.currentRound;
    }

    /**
     * 获取玩家列表
     */
    public getPlayers(): string[] {
        return this.players;
    }

    /**
     * 获取缓存的战斗结果
     */
    public getBattleResult(): BattleResultData {
        return this.battleResult;
    }

    /**
     * 获取当前战斗状态
     * @returns 战斗中状态缓存模型
     */
    public getBattleMemModel(): BattleMemModel {
        return {
            status: this.status,
            players: this.players,
            battleResult: this.battleResult,
            currentRound: this.currentRound,
            currentRoundCommands: this.currentRoundCommands,
            currentRoundEntities: this.currentRoundEntities,
            currentRoundNewEntities: this.currentRoundNewEntities,
        };
    }

    /**
     * 获取完整的战斗状态
     * @returns 包含所有游戏信息的状态对象
     */
    public getState(): GameStateModel {
        if (!this.map) {
            return {
                status: BattleStatus.init,
                initialized: false,
                battleEnded: this.isBattleEnded(),
                currentRound: this.currentRound,
                players: {},
                map: {
                    width: 50,
                    height: 50,
                    terrain: [],
                },
                battleResult: null,
            };
        }

        // 获取所有玩家
        const players = this.map.getAllPlayers();

        // 构建玩家信息
        const playersInfo: { [playerId: string]: PlayerInfoModel } = {};
        players.forEach((player) => {
            playersInfo[String(player.getId())] = {
                id: player.getId(),
                playerType: player.getPlayerType(),
                rmb: player.getRmb(),
                baseHealth: player.getBaseHealth(),
                units: player.getAllUnits(),
                buildings: player.getAllBuildings(),
                stats: {
                    kills: player.getKills(),
                    deaths: player.getDeaths(),
                    totalDamageDealt: player.getTotalDamageDealt(),
                    totalDamageReceived: player.getTotalDamageReceived(),
                    totalHealing: player.getTotalHealing(),
                    commandFailCount: player.getCommandFailCount(),
                },
            };
        });

        // 获取地图信息
        const mapData = this.map.map;

        return {
            status: this.status,
            initialized: true,
            battleEnded: this.isBattleEnded(),
            currentRound: this.currentRound,
            players: playersInfo,
            map:{
                width: mapData[0].length,
                height: mapData.length,
                terrain: mapData,
            },
            battleResult: this.battleResult,
        };
    }

    /**
     * 设置日志记录器
     */
    public setLogger(logger: any): void {
        this.logger = logger;
    }

    /**
     * 内部日志记录方法
     */
    private _log(level: string, category: string, message: string, data: any = null): void {
        if (this.logger && typeof this.logger[level] === 'function') {
            this.logger[level](category, message, data);
        } else {
            const logMessage = `[${category}] ${message}`;
            if (level === 'error') {
                console.error(logMessage);
                if (data) {
                    console.error(data);
                }
            } else if (level === 'warn' || level === 'warning') {
                console.warn(logMessage);
                if (data) {
                    console.warn(data);
                }
            } else {
                console.log(logMessage);
                if (data) {
                    console.log(data);
                }
            }
        }
    }

    /**
     * 重置战斗系统
     */
    public reset(): void {
        // 重置战斗状态
        this.currentRound = 0;
        this.players = [];
        this.currentRoundCommands = {};
        this.currentRoundEntities.clear();
        this.currentRoundNewEntities.clear();
        this.battleResult = null;
        this.status = BattleStatus.init;

        // 重置核心组件为null
        this.map = null;
        this.factory = null;
        this.validator = null;

        // 重置日志记录器
        this.logger = null;
    }
}
